/*
 * "Hello World" example.
 *
 * This example prints 'Hello from Nios II' to the STDOUT stream. It runs on
 * the Nios II 'standard', 'full_featured', 'fast', and 'low_cost' example
 * designs. It runs with or without the MicroC/OS-II RTOS and requires a STDOUT
 * device in your system's hardware.
 * The memory footprint of this hosted application is ~69 kbytes by default
 * using the standard reference design.
 *
 * For a reduced footprint version of this template, and an explanation of how
 * to reduce the memory footprint for a given application, see the
 * "small_hello_world" template.
 *
 */

#include "sys/alt_stdio.h"
#include "altera_up_avalon_audio.h"

//FIR filter, averages 64 consecutive words of speech
#define N 8
#define SAMPLING_RATE 32000


int main()
{
	//printf("Hello from Nios II!\n");
	alt_up_audio_dev * audio_dev;
	/* used for audio record/playback */
	signed short int l_buf;
	signed short int r_buf;
	signed short int r_total[N], l_total[N] = {0};
	signed short int r_total_n, l_total_n, i = 0;

	signed short int cache_r [SAMPLING_RATE] = {0};
	signed short int cache_l [SAMPLING_RATE] = {0};
	signed short int cache_r2 [SAMPLING_RATE*2] = {0};
	signed short int cache_l2 [SAMPLING_RATE*2] = {0};
	signed short int cache_r3 [SAMPLING_RATE*4] = {0};
	signed short int cache_l3 [SAMPLING_RATE*4] = {0};

	unsigned int k = 0;
	unsigned int l = 0;
	unsigned int h = 0;


	// open the Audio port
	audio_dev = alt_up_audio_open_dev (AUDIO_0_NAME);
	if ( audio_dev == NULL)
		alt_putstr("Error: could not open audio device \n");
	else
		alt_putstr("Opened audio device \n");
	srand(time(NULL));
	int r;
	/* read and echo audio data */
	while(1)
	{
		int fifospace = alt_up_audio_read_fifo_avail (audio_dev, ALT_UP_AUDIO_RIGHT);

		if ( fifospace > 0 ) // check if data is available
		{
			int j;
			signed short int temp_r, temp_l = 0;
			// read audio buffer
			alt_up_audio_read_fifo (audio_dev, &(r_buf), 1, ALT_UP_AUDIO_RIGHT);
			alt_up_audio_read_fifo (audio_dev, &(l_buf), 1, ALT_UP_AUDIO_LEFT);

			/*/adding noise -- FIR REALLY WORKS! N = 16 works really well
			r = rand () % 100;
			r_buf = r_buf - r;
			l_buf = l_buf - r;
			*/


			r_total[i] = r_buf/N;
			l_total[i] = l_buf/N;

			i++;

//			alt_printf("r_buf = %x\n ", r_buf);
	//		alt_printf("l_buf = %x\n ", l_buf);

			//alt_printf("i = %x\n ", i);
			if (i == N) {
				i = 0;
			}
			for (j = 0; j < N; j++) {
				r_total_n = r_total_n + r_total[j];
				l_total_n = l_total_n + l_total[j];
			}



			r_total_n = r_total_n/1;
			l_total_n = l_total_n/1;

				//alt_printf("k = %x\n ", k);


				//alt_printf("r_buf = %x\n ", cache_r[k-1]);

				//for (k = 0; k < 32000; k++) {
					//alt_printf("cache[%x] = %x\n ",k, cache_r[k]);

					// write audio buffer
//			alt_up_audio_write_fifo (audio_dev, &(cache_r[k]), 1, ALT_UP_AUDIO_RIGHT);
//			alt_up_audio_write_fifo (audio_dev, &(cache_l[k]), 1, ALT_UP_AUDIO_LEFT);
			//	}	
			if (k == SAMPLING_RATE) {
				k = 0;
			}
		/*	if (l == SAMPLING_RATE*2) {
				l = 0;
			}
			if (h == SAMPLING_RATE*3) {
				h = 0;
			}
*/
			temp_r = r_total_n;
			temp_l = l_total_n;
			// add "old" cache to r_total for echo effect
			r_total_n += cache_r[k]/16;
			l_total_n += cache_l[k]/16;
		//	r_total_n += cache_r2[l]/4;
		//	l_total_n += cache_l2[l]/4;
		//	r_total_n += cache_r3[h]/8;
		//	l_total_n += cache_l3[h]/8;

			// write audio buffer
			alt_up_audio_write_fifo (audio_dev, &(r_total_n), 1, ALT_UP_AUDIO_RIGHT);
			alt_up_audio_write_fifo (audio_dev, &(l_total_n), 1, ALT_UP_AUDIO_LEFT);

			// store current audio into cache[k] then increment k. basically updates old cache 
			// that was just outputted to what was just said so the next time we get to it,
			// it spits the last second's worth of audio
			cache_r [k] = temp_r;
			cache_l [k] = temp_l;
			//cache_r2 [l] = temp_r;
		//	cache_l2 [l] = temp_l;
		//	cache_r3 [h] = temp_r;
		//	cache_l3 [h] = temp_l;
			k++;
		//	l++;
		//	h++;


			r_total_n = 0;
			l_total_n = 0;
		}

	}

	alt_putstr("closed audio device \n");



  return 0;
}
